package com.surpassun.emall.service.impl;

import java.util.ArrayList;
import java.util.List;

import javax.inject.Inject;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.surpassun.emall.exception.NoSuchRoleException;
import com.surpassun.emall.model.Permission;
import com.surpassun.emall.model.Role;
import com.surpassun.emall.repository.PermissionRepository;
import com.surpassun.emall.repository.RoleRepository;
import com.surpassun.emall.service.RoleService;
import com.surpassun.emall.util.Constants;
import com.surpassun.emall.util.QueryUtil;
import com.surpassun.emall.util.Validator;

/**
 *
 * @author Denis
 */
@Service
public class RoleServiceImpl extends AbstractServiceImpl<Role> implements RoleService {
	
	private Logger _log = LoggerFactory.getLogger(RoleServiceImpl.class);

	@Inject
	RoleRepository roleRepository;
	
	@Inject
	PermissionRepository permissionRepository;
	
    public RoleServiceImpl() {
    	super(Role.class);
    }

	@Override
	public void addRole(String name, String description, List<Permission> permissions) {
		if (Validator.isNotNull(name)) {
			Role role = new Role(name, description, permissions);
			roleRepository.add(role);
		}
	}

	@Override
	public void updateRole(Role role, String name, String description, List<Permission> permissions) {
		if (Validator.isNotNull(role) && Validator.isNotNull(name)) {
			role.setName(name);
			role.setDescription(description);
			role.setPermissions(permissions);
			roleRepository.update(role);
		}
	}

	@Override
	public void updateRole(long roleId, String name, String description, List<Permission> permissions) throws NoSuchRoleException {
		Role role = roleRepository.get(roleId);
		if (Validator.isNull(role)) {
			throw new NoSuchRoleException("No such role exsit with the id : " + roleId);
		}
		
		this.updateRole(role, name, description, permissions);
	}

	@Override
	public void updateRolePermissions(Role role, List<Permission> permissions) {
		if (Validator.isNotNull(role)) {
			role.setPermissions(permissions);
			roleRepository.update(role);
		}
	}
	
	@Override
	public void updateRolePermissions(long roleId, List<Permission> permissions) throws NoSuchRoleException {
		Role role = roleRepository.get(roleId);
		if (Validator.isNull(role)) {
			throw new NoSuchRoleException("No such role exsit with the id : " + roleId);
		}
		
		this.updateRolePermissions(role, permissions);
	}

	@Override
	public void addRolePermissions(Role role, List<Permission> permissions) {
		if (Validator.isNotNull(role)) {
			//get the existed permissions
			List<Permission> oldPermissions = role.getPermissions();
			if (Validator.isNull(oldPermissions)) {
				oldPermissions = new ArrayList<Permission>();
			}
			
			//add the new permissions to the existed ones
			oldPermissions.addAll(permissions);
			
			//merge the permissions and save them
			role.setPermissions(oldPermissions);
			roleRepository.update(role);
		}
	}
	
	@Override
	public void addRolePermissions(long roleId, List<Permission> permissions) throws NoSuchRoleException {
		Role role = roleRepository.get(roleId);
		if (Validator.isNull(role)) {
			throw new NoSuchRoleException("No such role exsit with the id : " + roleId);
		}
		
		this.addRolePermissions(role, permissions);
	}

	@Override
	public Role addRoleAdmin() {
		List<Role> roles = roleRepository.getByField("name", Constants.ROLE_NAME_ADMIN, QueryUtil.EQUAL);
		//Add admin role if it doesn't exist
		if (Validator.isEmpty(roles)) {
			List<Permission> permissions = permissionRepository.getByField("name", Constants.PERMISSION_ACTION_ACCESS_ADMIN_PAGE, QueryUtil.EQUAL);
			Role role = new Role(Constants.ROLE_NAME_ADMIN, "");
			roleRepository.add(role);
			role.setPermissions(permissions);
			roleRepository.update(role);
			_log.info("Role " + Constants.ROLE_NAME_ADMIN + " added");
			
			return role;
		} else {
			return roles.get(0);
		}
	}
	
	@Override
	public Role getRole(String roleName) {
		return roleRepository.getRole(roleName);
	}
}